diff --git a/src/cryptonote_basic/miner.cpp b/src/cryptonote_basic/miner.cpp index 4b3d511e1..b82dc523b 100644 --- a/src/cryptonote_basic/miner.cpp +++ b/src/cryptonote_basic/miner.cpp @@ -175,7 +175,8 @@ namespace cryptonote uint64_t seed_height; crypto::hash seed_hash; - if(!m_phandler->get_block_template(bl, m_mine_address, di, height, expected_reward, extra_nonce, seed_height, seed_hash)) + crypto::public_key miner_reward_tx_key; + if(!m_phandler->get_block_template(bl, m_mine_address, di, height, expected_reward, extra_nonce, seed_height, seed_hash, miner_reward_tx_key)) { LOG_ERROR("Failed to get_block_template(), stopping mining"); m_forced_stop = true; diff --git a/src/cryptonote_basic/miner.h b/src/cryptonote_basic/miner.h index 3f4f36679..a6e6dd1d2 100644 --- a/src/cryptonote_basic/miner.h +++ b/src/cryptonote_basic/miner.h @@ -47,7 +47,7 @@ namespace cryptonote struct i_miner_handler { virtual bool handle_block_found(block& b, block_verification_context &bvc) = 0; - virtual bool get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash) = 0; + virtual bool get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash, crypto::public_key &miner_reward_tx_key) = 0; protected: ~i_miner_handler(){}; }; diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index f8a02ca9b..64f40a1be 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -323,7 +323,7 @@ namespace config const uint64_t STAKE_LOCK_PERIOD = 30*24*30; const uint64_t TREASURY_SAL1_MINT_PERIOD = 30*24*30; // 1 month of blocks - std::string const TREASURY_ADDRESS_CARROT = "SC11sFBPrGmNuT8AiTPUW479BwkdPJwBxdjKEhZ96yDfFg3B4mawgcpE1YfCAa1zwzUiRTMP9eqB54av48ALhzUu1Q5QoPGUfh"; + std::string const TREASURY_ADDRESS_CARROT = "SC11ksHLFhy7H1yMk9bUZvADG1Z9ZkR1T5QMknm3RbGBbgdPkyanB2WBb5TER3MsiwJC5BnyoiYs2DBcvAfAm6JQ537iNKdtvm"; std::string const TREASURY_ADDRESS = "SaLvdZR6w1A21sf2Wh6jYEh1wzY4GSbT7RX6FjyPsnLsffWLrzFQeXUXJcmBLRWDzZC2YXeYe5t7qKsnrg9FpmxmEcxPHsEYfqA"; // treasury payout {tx-key, output-key, anchor_enc, view_tag} tuples diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 48c97a290..ed134f31b 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1560,7 +1560,7 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl treasury_index_in_tx_outputs = index_in_tx_outputs; } - //validate reward + // Calculate reward being issued uint64_t money_in_use = 0; CHECK_AND_ASSERT_MES(b.miner_tx.amount_burnt > 0 || height == 0, false, "invalid tx.amount_burnt for miner_tx"); CHECK_AND_ASSERT_MES(money_in_use + b.miner_tx.amount_burnt >= money_in_use, false, "miner transaction is overflowed by amount_burnt"); @@ -1576,6 +1576,25 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl } partial_block_reward = false; + // Make sure the TOTAL REWARD is correct + uint64_t median_weight = m_current_block_cumul_weight_median; + if (!get_block_reward(median_weight, cumulative_block_weight, already_generated_coins, base_reward, version)) + { + MERROR_VER("block weight " << cumulative_block_weight << " is bigger than allowed for this blockchain"); + return false; + } + if(base_reward + fee < money_in_use) + { + MERROR_VER("coinbase transaction spend too much money (" << print_money(money_in_use) << "). Block reward is " << print_money(base_reward + fee) << "(" << print_money(base_reward) << "+" << print_money(fee) << "), cumulative_block_weight " << cumulative_block_weight); + return false; + } + if(base_reward + fee != money_in_use) + { + MDEBUG("coinbase transaction doesn't use full amount of block reward: spent: " << money_in_use << ", block reward " << base_reward + fee << "(" << base_reward << "+" << fee << ")"); + return false; + } + + // HF-specific additional checks switch (version) { case HF_VERSION_BULLETPROOF_PLUS: case HF_VERSION_ENABLE_N_OUTS: @@ -1596,12 +1615,6 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl // HF11: block reward split is 60% miner + 25% treasury + 15% staker (amount_burnt) if (already_generated_coins != 0) { - // Make sure we have the correct number of outputs - if (treasury_payout_exists) - CHECK_AND_ASSERT_MES(b.miner_tx.vout.size() == 3, false, "Incorrect number of miner_tx outputs (expected 3)"); - else - CHECK_AND_ASSERT_MES(b.miner_tx.vout.size() == 2, false, "Incorrect number of miner_tx outputs (expected 2)"); - // Validate treasury share: one output must equal block_reward * 25 / 100 uint64_t expected_treasury_block_reward = money_in_use * BLOCK_REWARD_TREASURY_PCT / 100; // Validate staker share: amount_burnt == block_reward * 15 / 100 @@ -1638,12 +1651,14 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl std::vector additional_tx_pubkeys = cryptonote::get_additional_tx_pub_keys_from_extra(b.miner_tx.extra); bool found_treasury_block_reward = false; - bool found_miner_block_reward = false; for (size_t i = 0; i < b.miner_tx.vout.size(); i++) { // Get the output CHECK_AND_ASSERT_MES(b.miner_tx.vout[i].target.type() == typeid(txout_to_carrot_v1), false, "Output of miner_tx is not txout_to_carrot_V1"); const auto &output = boost::get(b.miner_tx.vout[i].target); + + // Check the output type is SAL1 + CHECK_AND_ASSERT_MES(output.asset_type == "SAL1", false, "Output of miner_tx is not SAL1"); // Skip the premine remint if (treasury_payout_exists && (i == treasury_index_in_tx_outputs)) continue; @@ -1677,17 +1692,8 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl found_treasury_block_reward = true; continue; } - if (b.miner_tx.vout[i].amount == expected_miner_block_reward) { - std::string miner_out_asset_type; - cryptonote::get_output_asset_type(b.miner_tx.vout[i], miner_out_asset_type); - CHECK_AND_ASSERT_MES(miner_out_asset_type == "SAL1", false, - "miner output has wrong asset_type: expected SAL1, got " << miner_out_asset_type); - found_miner_block_reward = true; - continue; - } } CHECK_AND_ASSERT_MES(found_treasury_block_reward, false, "miner_tx missing treasury output with expected amount " << expected_treasury_block_reward); - CHECK_AND_ASSERT_MES(found_miner_block_reward, false, "miner_tx missing miner output with expected amount " << expected_miner_block_reward); } break; default: @@ -1695,22 +1701,6 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl break; } - uint64_t median_weight = m_current_block_cumul_weight_median; - if (!get_block_reward(median_weight, cumulative_block_weight, already_generated_coins, base_reward, version)) - { - MERROR_VER("block weight " << cumulative_block_weight << " is bigger than allowed for this blockchain"); - return false; - } - if(base_reward + fee < money_in_use) - { - MERROR_VER("coinbase transaction spend too much money (" << print_money(money_in_use) << "). Block reward is " << print_money(base_reward + fee) << "(" << print_money(base_reward) << "+" << print_money(fee) << "), cumulative_block_weight " << cumulative_block_weight); - return false; - } - if(base_reward + fee != money_in_use) - { - MDEBUG("coinbase transaction doesn't use full amount of block reward: spent: " << money_in_use << ", block reward " << base_reward + fee << "(" << base_reward << "+" << fee << ")"); - return false; - } return true; } //------------------------------------------------------------------ @@ -2041,7 +2031,7 @@ uint64_t Blockchain::get_current_cumulative_block_weight_median() const // in a lot of places. That flag is not referenced in any of the code // nor any of the makefiles, howeve. Need to look into whether or not it's // necessary at all. -bool Blockchain::create_block_template(block& b, const crypto::hash *from_block, const account_public_address& miner_address, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash) +bool Blockchain::create_block_template(block& b, const crypto::hash *from_block, const account_public_address& miner_address, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash, crypto::public_key &miner_reward_tx_key) { LOG_PRINT_L3("Blockchain::" << __func__); size_t median_weight; @@ -2449,7 +2439,7 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block, uint8_t hf_version = b.major_version; size_t max_outs = hf_version >= HF_VERSION_ENABLE_TOKENS ? 3 : (hf_version >= 4 ? 1 : 11); - bool r = construct_miner_tx(height, median_weight, already_generated_coins, txs_weight, fee, miner_address, b.miner_tx, m_nettype, m_hardfork->get_hardforks(), ex_nonce, max_outs, hf_version); + bool r = construct_miner_tx(height, median_weight, already_generated_coins, txs_weight, fee, miner_address, miner_reward_tx_key, b.miner_tx, m_nettype, m_hardfork->get_hardforks(), ex_nonce, max_outs, hf_version); CHECK_AND_ASSERT_MES(r, false, "Failed to construct miner tx, first chance"); size_t cumulative_weight = txs_weight + get_transaction_weight(b.miner_tx); #if defined(DEBUG_CREATE_BLOCK_TEMPLATE) @@ -2458,7 +2448,7 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block, #endif for (size_t try_count = 0; try_count != 10; ++try_count) { - r = construct_miner_tx(height, median_weight, already_generated_coins, cumulative_weight, fee, miner_address, b.miner_tx, m_nettype, m_hardfork->get_hardforks(), ex_nonce, max_outs, hf_version); + r = construct_miner_tx(height, median_weight, already_generated_coins, cumulative_weight, fee, miner_address, miner_reward_tx_key, b.miner_tx, m_nettype, m_hardfork->get_hardforks(), ex_nonce, max_outs, hf_version); CHECK_AND_ASSERT_MES(r, false, "Failed to construct miner tx, second chance"); size_t coinbase_weight = get_transaction_weight(b.miner_tx); @@ -2510,9 +2500,9 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block, return false; } //------------------------------------------------------------------ -bool Blockchain::create_block_template(block& b, const account_public_address& miner_address, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash) +bool Blockchain::create_block_template(block& b, const account_public_address& miner_address, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash, crypto::public_key &miner_reward_tx_key) { - return create_block_template(b, NULL, miner_address, diffic, height, expected_reward, ex_nonce, seed_height, seed_hash); + return create_block_template(b, NULL, miner_address, diffic, height, expected_reward, ex_nonce, seed_height, seed_hash, miner_reward_tx_key); } //------------------------------------------------------------------ bool Blockchain::get_miner_data(uint8_t& major_version, uint64_t& height, crypto::hash& prev_id, crypto::hash& seed_hash, difficulty_type& difficulty, uint64_t& median_weight, uint64_t& already_generated_coins, std::vector& tx_backlog) diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index c3348fdfc..4422d7d81 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -394,8 +394,8 @@ namespace cryptonote * * @return true if block template filled in successfully, else false */ - bool create_block_template(block& b, const account_public_address& miner_address, difficulty_type& di, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash); - bool create_block_template(block& b, const crypto::hash *from_block, const account_public_address& miner_address, difficulty_type& di, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash); + bool create_block_template(block& b, const account_public_address& miner_address, difficulty_type& di, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash, crypto::public_key &miner_reward_tx_key); + bool create_block_template(block& b, const crypto::hash *from_block, const account_public_address& miner_address, difficulty_type& di, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash, crypto::public_key &miner_reward_tx_key); /** * @brief gets data required to create a block template and start mining on it diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index ea3e54680..d0639787d 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -1542,14 +1542,14 @@ namespace cryptonote notify_txpool_event(tx_blobs, epee::to_span(tx_hashes), epee::to_span(txs), just_broadcasted); } //----------------------------------------------------------------------------------------------- - bool core::get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash) + bool core::get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash, crypto::public_key &miner_reward_tx_key) { - return m_blockchain_storage.create_block_template(b, adr, diffic, height, expected_reward, ex_nonce, seed_height, seed_hash); + return m_blockchain_storage.create_block_template(b, adr, diffic, height, expected_reward, ex_nonce, seed_height, seed_hash, miner_reward_tx_key); } //----------------------------------------------------------------------------------------------- - bool core::get_block_template(block& b, const crypto::hash *prev_block, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash) + bool core::get_block_template(block& b, const crypto::hash *prev_block, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash, crypto::public_key &miner_reward_tx_key) { - return m_blockchain_storage.create_block_template(b, prev_block, adr, diffic, height, expected_reward, ex_nonce, seed_height, seed_hash); + return m_blockchain_storage.create_block_template(b, prev_block, adr, diffic, height, expected_reward, ex_nonce, seed_height, seed_hash, miner_reward_tx_key); } //----------------------------------------------------------------------------------------------- bool core::get_miner_data(uint8_t& major_version, uint64_t& height, crypto::hash& prev_id, crypto::hash& seed_hash, difficulty_type& difficulty, uint64_t& median_weight, uint64_t& already_generated_coins, std::vector& tx_backlog) diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index 143403de8..01e648f9f 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -231,8 +231,8 @@ namespace cryptonote * * @note see Blockchain::create_block_template */ - virtual bool get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash) override; - virtual bool get_block_template(block& b, const crypto::hash *prev_block, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash); + virtual bool get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash, crypto::public_key &miner_reward_tx_key) override; + virtual bool get_block_template(block& b, const crypto::hash *prev_block, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash, crypto::public_key &miner_reward_tx_key); /** * @copydoc Blockchain::get_miner_data diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp index e7b9d1a38..54e9a0dbb 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.cpp +++ b/src/cryptonote_core/cryptonote_tx_utils.cpp @@ -469,7 +469,7 @@ namespace cryptonote return treasury_anchor; } //--------------------------------------------------------------- - bool construct_miner_tx(size_t height, size_t median_weight, uint64_t already_generated_coins, size_t current_block_weight, uint64_t fee, const account_public_address &miner_address, transaction& tx, network_type nettype, const std::vector& hardforks, const blobdata& extra_nonce, size_t max_outs, uint8_t hard_fork_version) { + bool construct_miner_tx(size_t height, size_t median_weight, uint64_t already_generated_coins, size_t current_block_weight, uint64_t fee, const account_public_address &miner_address, crypto::public_key& miner_reward_tx_key, transaction& tx, network_type nettype, const std::vector& hardforks, const blobdata& extra_nonce, size_t max_outs, uint8_t hard_fork_version) { // Clear the TX contents tx.set_null(); @@ -528,6 +528,9 @@ namespace cryptonote std::vector enotes(num_enotes); carrot::get_coinbase_output_proposal_v1(miner_proposal, height, enotes[0]); + // STORE THE MINER TX_PUB_KEY NOW + miner_reward_tx_key = carrot::raw_byte_convert(enotes[0].enote_ephemeral_pubkey); + size_t enote_idx = 1; // Add the treasury reward enote (25% of block reward) for HF11+ @@ -600,6 +603,8 @@ namespace cryptonote keypair txkey = keypair::generate(hw::get_device("default")); add_tx_pub_key_to_extra(tx, txkey.pub); + // STORE THE MINER TX_PUB_KEY NOW + miner_reward_tx_key = txkey.pub; if(!extra_nonce.empty()) if(!add_extra_nonce_to_tx_extra(tx.extra, extra_nonce)) return false; diff --git a/src/cryptonote_core/cryptonote_tx_utils.h b/src/cryptonote_core/cryptonote_tx_utils.h index 47ec029d0..026eba3ca 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.h +++ b/src/cryptonote_core/cryptonote_tx_utils.h @@ -79,7 +79,7 @@ namespace cryptonote //--------------------------------------------------------------- carrot::janus_anchor_t get_deterministic_treasury_anchor_from_height(uint64_t height); //--------------------------------------------------------------- - bool construct_miner_tx(size_t height, size_t median_weight, uint64_t already_generated_coins, size_t current_block_weight, uint64_t fee, const account_public_address &miner_address, transaction& tx, network_type nettype = network_type::FAKECHAIN, const std::vector& hardforks = {}, const blobdata& extra_nonce = blobdata(), size_t max_outs = 999, uint8_t hard_fork_version = 1); + bool construct_miner_tx(size_t height, size_t median_weight, uint64_t already_generated_coins, size_t current_block_weight, uint64_t fee, const account_public_address &miner_address, crypto::public_key& miner_reward_tx_key, transaction& tx, network_type nettype = network_type::FAKECHAIN, const std::vector& hardforks = {}, const blobdata& extra_nonce = blobdata(), size_t max_outs = 999, uint8_t hard_fork_version = 1); struct tx_source_entry { diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index f3935a207..87c14409a 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -149,7 +149,8 @@ void print_genesis_tx_hex(const cryptonote::network_type nettype) { //Prepare genesis_tx cryptonote::transaction tx_genesis; - cryptonote::construct_miner_tx(0, 0, 0, 10, 0, miner_acc1.get_keys().m_account_address, tx_genesis, (network_type)nettype, {}, blobdata(), 999, 1); + crypto::public_key miner_reward_tx_key = crypto::null_pkey; + cryptonote::construct_miner_tx(0, 0, 0, 10, 0, miner_acc1.get_keys().m_account_address, miner_reward_tx_key, tx_genesis, (network_type)nettype, {}, blobdata(), 999, 1); std::cout << "Object:" << std::endl; std::cout << obj_to_json_str(tx_genesis) << std::endl << std::endl; diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index a47d8bed7..b9e643ea8 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -1871,40 +1871,22 @@ namespace cryptonote bool core_rpc_server::get_block_template(const account_public_address &address, const crypto::hash *prev_block, const cryptonote::blobdata &extra_nonce, size_t &reserved_offset, cryptonote::difficulty_type &difficulty, uint64_t &height, uint64_t &expected_reward, block &b, uint64_t &seed_height, crypto::hash &seed_hash, crypto::hash &next_seed_hash, epee::json_rpc::error &error_resp) { b = boost::value_initialized(); - if(!m_core.get_block_template(b, prev_block, address, difficulty, height, expected_reward, extra_nonce, seed_height, seed_hash)) + crypto::public_key tx_pub_key = crypto::null_pkey; + if(!m_core.get_block_template(b, prev_block, address, difficulty, height, expected_reward, extra_nonce, seed_height, seed_hash, tx_pub_key)) { error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; error_resp.message = "Internal error: failed to create block template"; LOG_ERROR("Failed to create block template"); return false; } - blobdata block_blob = t_serializable_object_to_blob(b); - crypto::public_key tx_pub_key = cryptonote::get_tx_pub_key_from_extra(b.miner_tx); - const std::vector additional_tx_pub_keys = cryptonote::get_additional_tx_pub_keys_from_extra(b.miner_tx); if(tx_pub_key == crypto::null_pkey) { - // Check for Carrot treasury payout - const uint8_t hf_version = m_core.get_blockchain_storage().get_current_hard_fork_version(); - if (hf_version >= HF_VERSION_CARROT && b.miner_tx.vout.size() == 2) { - - const auto treasury_payout_data = get_config(nettype()).TREASURY_SAL1_MINT_OUTPUT_DATA; - const bool treasury_payout_exists = (treasury_payout_data.count(height) == 1); - if (!treasury_payout_exists) { - error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; - error_resp.message = "Internal error: failed to create block template (missing treasury payout)"; - LOG_ERROR("Failed to get tx pub key in coinbase extra (missing treasury payout)"); - return false; - } - tx_pub_key = additional_tx_pub_keys.back(); - - } else { - error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; - error_resp.message = "Internal error: failed to create block template"; - LOG_ERROR("Failed to get tx pub key in coinbase extra"); - return false; - } + error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; + error_resp.message = "Internal error: failed to create block template"; + LOG_ERROR("Failed to get tx pub key in coinbase extra"); + return false; } - + blobdata block_blob = t_serializable_object_to_blob(b); uint64_t next_height; crypto::rx_seedheights(height, &seed_height, &next_height); if (next_height != seed_height)