diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 1c85df9f..8de65d46 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -1345,7 +1345,12 @@ bool blockchain_storage::validate_miner_transaction(const block& b, return false; } - uint64_t block_reward = base_reward + fee; + uint64_t block_reward = base_reward; + // before HF4: add tx fee to the block reward; after HF4: burn it + if (b.miner_tx.version < TRANSACTION_VERSION_POST_HF4) + { + block_reward += fee; + } crypto::hash tx_id_for_post_hf4_era = b.miner_tx.version > TRANSACTION_VERSION_PRE_HF4 ? get_transaction_hash(b.miner_tx) : null_hash; if (!check_tx_balance(b.miner_tx, tx_id_for_post_hf4_era, block_reward)) @@ -1519,6 +1524,7 @@ bool blockchain_storage::create_block_template(const create_block_template_param stakeholder_address, b.miner_tx, resp.block_reward_without_fee, + resp.block_reward, get_tx_version(height, m_core_runtime_config.hard_forks), ex_nonce, CURRENCY_MINER_TX_MAX_OUTS, @@ -6663,6 +6669,10 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt return false; } bei.already_generated_coins = already_generated_coins - burned_coins + base_reward; + if (bei.bl.miner_tx.version >= TRANSACTION_VERSION_POST_HF4) + { + bei.already_generated_coins -= fee_summary; + } auto blocks_index_ptr = m_db_blocks_index.get(id); if (blocks_index_ptr) diff --git a/src/currency_core/blockchain_storage_basic.h b/src/currency_core/blockchain_storage_basic.h index 75d8f3ce..27908fbf 100644 --- a/src/currency_core/blockchain_storage_basic.h +++ b/src/currency_core/blockchain_storage_basic.h @@ -148,6 +148,7 @@ namespace currency uint64_t height; tx_generation_context miner_tx_tgc; // bad design, a lot of copying, consider redesign -- sowle uint64_t block_reward_without_fee; + uint64_t block_reward; // == block_reward_without_fee + txs_fee if fees are given to the miner, OR block_reward_without_fee if fees are burnt uint64_t txs_fee; // sum of transactions' fee if any }; diff --git a/src/currency_core/currency_config.h b/src/currency_core/currency_config.h index 39622e99..39b0a9e0 100644 --- a/src/currency_core/currency_config.h +++ b/src/currency_core/currency_config.h @@ -10,7 +10,7 @@ #ifndef TESTNET #define CURRENCY_FORMATION_VERSION 84 #else -#define CURRENCY_FORMATION_VERSION 93 +#define CURRENCY_FORMATION_VERSION 94 #endif #define CURRENCY_GENESIS_NONCE (CURRENCY_FORMATION_VERSION + 101011010121) //bender's nightmare @@ -273,7 +273,7 @@ #define ZANO_HARDFORK_01_AFTER_HEIGHT 0 #define ZANO_HARDFORK_02_AFTER_HEIGHT 0 #define ZANO_HARDFORK_03_AFTER_HEIGHT 0 -#define ZANO_HARDFORK_04_AFTER_HEIGHT 4440 +#define ZANO_HARDFORK_04_AFTER_HEIGHT 2440 #endif diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 27cf9417..5b448f53 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -361,6 +361,7 @@ namespace currency const account_public_address &stakeholder_address, transaction& tx, uint64_t& block_reward_without_fee, + uint64_t& block_reward, uint64_t tx_version, const blobdata& extra_nonce /* = blobdata() */, size_t max_outs /* = CURRENCY_MINER_TX_MAX_OUTS */, @@ -380,7 +381,13 @@ namespace currency LOG_ERROR("Block is too big"); return false; } - uint64_t block_reward = block_reward_without_fee + fee; + + block_reward = block_reward_without_fee; + // before HF4: add tx fee to the block reward; after HF4: burn it + if (tx_version < TRANSACTION_VERSION_POST_HF4) + { + block_reward += fee; + } if (!destinations.size()) { diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 3493c6c6..bb1dbb70 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -274,6 +274,7 @@ namespace currency const account_public_address &stakeholder_address, transaction& tx, uint64_t& block_reward_without_fee, + uint64_t& block_reward, uint64_t tx_version, const blobdata& extra_nonce = blobdata(), size_t max_outs = CURRENCY_MINER_TX_MAX_OUTS, diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 3dcc6719..6178141c 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -950,6 +950,7 @@ namespace currency res.miner_tx_tgc = resp.miner_tx_tgc; res.height = resp.height; res.block_reward_without_fee = resp.block_reward_without_fee; + res.block_reward = resp.block_reward; res.txs_fee = resp.txs_fee; //calculate epoch seed res.seed = currency::ethash_epoch_to_seed(currency::ethash_height_to_epoch(res.height)); diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 3570139b..79a343de 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -927,6 +927,7 @@ namespace currency std::string prev_hash; tx_generation_context miner_tx_tgc; uint64_t block_reward_without_fee; + uint64_t block_reward; // == block_reward_without_fee + txs_fee if fees are given to the miner, OR block_reward_without_fee if fees are burnt uint64_t txs_fee; std::string status; @@ -938,6 +939,7 @@ namespace currency KV_SERIALIZE(prev_hash) KV_SERIALIZE(miner_tx_tgc) KV_SERIALIZE(block_reward_without_fee) + KV_SERIALIZE(block_reward) KV_SERIALIZE(txs_fee) KV_SERIALIZE(status) END_KV_SERIALIZE_MAP() diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index cf80e66e..d4b19270 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4601,8 +4601,7 @@ bool wallet2::build_minted_block(const mining_context& cxt, const currency::acco set_block_datetime(current_timestamp, b); WLT_LOG_MAGENTA("Applying actual timestamp: " << current_timestamp, LOG_LEVEL_2); - uint64_t full_block_reward = tmpl_rsp.block_reward_without_fee + tmpl_rsp.txs_fee; - res = prepare_and_sign_pos_block(cxt, full_block_reward, tmpl_req.pe, tmpl_rsp.miner_tx_tgc, b); + res = prepare_and_sign_pos_block(cxt, tmpl_rsp.block_reward, tmpl_req.pe, tmpl_rsp.miner_tx_tgc, b); WLT_CHECK_AND_ASSERT_MES(res, false, "Failed to prepare_and_sign_pos_block"); crypto::hash block_hash = get_block_hash(b); diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index 5f1bd767..16e564ef 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -300,6 +300,7 @@ bool test_generator::construct_block(currency::block& blk, size_t target_block_size = txs_size + 0; // zero means no cost for ordinary coinbase tx_generation_context miner_tx_tgc{}; uint64_t block_reward_without_fee = 0; + uint64_t block_reward = 0; while (true) { r = construct_miner_tx(height, misc_utils::median(block_sizes), @@ -310,6 +311,7 @@ bool test_generator::construct_block(currency::block& blk, miner_acc.get_keys().account_address, blk.miner_tx, block_reward_without_fee, + block_reward, get_tx_version(height, m_hardforks), blobdata(), test_generator::get_test_gentime_settings().miner_tx_max_outs, @@ -356,7 +358,7 @@ bool test_generator::construct_block(currency::block& blk, else { //need to build pos block - r = sign_block(wallets[won_walled_index].mining_context, pe, block_reward_without_fee + total_fee, *wallets[won_walled_index].wallet, miner_tx_tgc, blk); + r = sign_block(wallets[won_walled_index].mining_context, pe, block_reward, *wallets[won_walled_index].wallet, miner_tx_tgc, blk); CHECK_AND_ASSERT_MES(r, false, "Failed to find_kernel_and_sign()"); } @@ -951,9 +953,11 @@ bool test_generator::construct_block(int64_t manual_timestamp_adjustment, else { uint64_t base_block_reward = 0; + uint64_t block_reward = 0; size_t current_block_size = txs_sizes + get_object_blobsize(blk.miner_tx); // TODO: This will work, until size of constructed block is less then CURRENCY_BLOCK_GRANTED_FULL_REWARD_ZONE - if (!construct_miner_tx(height, misc_utils::median(block_sizes), already_generated_coins, current_block_size, 0, miner_acc.get_public_address(), miner_acc.get_public_address(), blk.miner_tx, base_block_reward, get_tx_version(height, m_hardforks), blobdata(), 1)) + if (!construct_miner_tx(height, misc_utils::median(block_sizes), already_generated_coins, current_block_size, 0, + miner_acc.get_public_address(), miner_acc.get_public_address(), blk.miner_tx, base_block_reward, block_reward, get_tx_version(height, m_hardforks), blobdata(), 1)) return false; } diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h index 9799e38c..690bdef5 100644 --- a/tests/core_tests/chaingen.h +++ b/tests/core_tests/chaingen.h @@ -957,10 +957,11 @@ bool test_generator::construct_block_gentime_with_coinbase_cb(const currency::bl //size_t current_block_size = get_object_blobsize(miner_tx); uint64_t block_reward_without_fee = 0; + uint64_t block_reward = 0; currency::keypair tx_sec_key = currency::keypair::generate(); r = construct_miner_tx(height, epee::misc_utils::median(block_sizes), already_generated_coins, 0 /* current_block_size !HACK! */, 0, - acc.get_public_address(), acc.get_public_address(), miner_tx, block_reward_without_fee, get_tx_version(height, m_hardforks), currency::blobdata(), /* max outs: */ 1, + acc.get_public_address(), acc.get_public_address(), miner_tx, block_reward_without_fee, block_reward, get_tx_version(height, m_hardforks), currency::blobdata(), /* max outs: */ 1, /* pos: */ false, currency::pos_entry(), /* ogc_ptr: */ nullptr, &tx_sec_key); CHECK_AND_ASSERT_MES(r, false, "construct_miner_tx failed"); diff --git a/tests/core_tests/multiassets_test.cpp b/tests/core_tests/multiassets_test.cpp index daa40637..93f394b0 100644 --- a/tests/core_tests/multiassets_test.cpp +++ b/tests/core_tests/multiassets_test.cpp @@ -154,7 +154,7 @@ bool multiassets_basic_test::c1(currency::core& c, size_t ev_index, const std::v CHECK_AND_ASSERT_MES(it_asset != balances.end() && it_native != balances.end(), false, "Failed to find needed asset in result balances"); CHECK_AND_ASSERT_MES(it_asset->second.total == AMOUNT_ASSETS_TO_TRANSFER_MULTIASSETS_BASIC, false, "Failed to find needed asset in result balances"); - CHECK_AND_ASSERT_MES(it_native->second.total == uint64_t(17517226)*COIN, false, "Failed to find needed asset in result balances"); + CHECK_AND_ASSERT_MES(it_native->second.total == uint64_t(17517225990000000000), false, "Failed to find needed asset in result balances"); balances.clear(); diff --git a/tests/core_tests/pos_block_builder.cpp b/tests/core_tests/pos_block_builder.cpp index 1d0ca60e..c96575b1 100644 --- a/tests/core_tests/pos_block_builder.cpp +++ b/tests/core_tests/pos_block_builder.cpp @@ -167,9 +167,10 @@ void pos_block_builder::step4_generate_coinbase_tx(size_t median_size, // generate miner tx using incorrect current_block_size only for size estimation uint64_t block_reward_without_fee = 0; + uint64_t block_reward = 0; size_t estimated_block_size = m_txs_total_size; bool r = construct_miner_tx(m_height, median_size, already_generated_coins, estimated_block_size, m_total_fee, - reward_receiver_address, stakeholder_address, m_block.miner_tx, block_reward_without_fee, tx_version, extra_nonce, max_outs, true, pe, &m_miner_tx_tgc, tx_one_time_key_to_use); + reward_receiver_address, stakeholder_address, m_block.miner_tx, block_reward_without_fee, block_reward, tx_version, extra_nonce, max_outs, true, pe, &m_miner_tx_tgc, tx_one_time_key_to_use); CHECK_AND_ASSERT_THROW_MES(r, "construct_miner_tx failed"); estimated_block_size = m_txs_total_size + get_object_blobsize(m_block.miner_tx); @@ -177,7 +178,7 @@ void pos_block_builder::step4_generate_coinbase_tx(size_t median_size, for (size_t try_count = 0; try_count != 10; ++try_count) { r = construct_miner_tx(m_height, median_size, already_generated_coins, estimated_block_size, m_total_fee, - reward_receiver_address, stakeholder_address, m_block.miner_tx, block_reward_without_fee, tx_version, extra_nonce, max_outs, true, pe, &m_miner_tx_tgc, tx_one_time_key_to_use); + reward_receiver_address, stakeholder_address, m_block.miner_tx, block_reward_without_fee, block_reward, tx_version, extra_nonce, max_outs, true, pe, &m_miner_tx_tgc, tx_one_time_key_to_use); CHECK_AND_ASSERT_THROW_MES(r, "construct_homemade_pos_miner_tx failed"); cumulative_size = m_txs_total_size + get_object_blobsize(m_block.miner_tx); diff --git a/tests/core_tests/transaction_tests.cpp b/tests/core_tests/transaction_tests.cpp index 58bf73d2..206a5596 100644 --- a/tests/core_tests/transaction_tests.cpp +++ b/tests/core_tests/transaction_tests.cpp @@ -35,23 +35,24 @@ bool test_transaction_generation_and_ring_signature() std::string add_str = miner_acc3.get_public_address_str(); uint64_t block_reward_without_fee = 0; + uint64_t block_reward = 0; account_base rv_acc; rv_acc.generate(); account_base rv_acc2; rv_acc2.generate(); transaction tx_mine_1; - construct_miner_tx(0, 0, 0, 10, 0, miner_acc1.get_keys().account_address, miner_acc1.get_keys().account_address, tx_mine_1, block_reward_without_fee, TRANSACTION_VERSION_PRE_HF4); + construct_miner_tx(0, 0, 0, 10, 0, miner_acc1.get_keys().account_address, miner_acc1.get_keys().account_address, tx_mine_1, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4); transaction tx_mine_2; - construct_miner_tx(0, 0, 0, 0, 0, miner_acc2.get_keys().account_address, miner_acc2.get_keys().account_address, tx_mine_2, block_reward_without_fee, TRANSACTION_VERSION_PRE_HF4); + construct_miner_tx(0, 0, 0, 0, 0, miner_acc2.get_keys().account_address, miner_acc2.get_keys().account_address, tx_mine_2, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4); transaction tx_mine_3; - construct_miner_tx(0, 0, 0, 0, 0, miner_acc3.get_keys().account_address, miner_acc3.get_keys().account_address, tx_mine_3, block_reward_without_fee, TRANSACTION_VERSION_PRE_HF4); + construct_miner_tx(0, 0, 0, 0, 0, miner_acc3.get_keys().account_address, miner_acc3.get_keys().account_address, tx_mine_3, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4); transaction tx_mine_4; - construct_miner_tx(0, 0, 0, 0, 0, miner_acc4.get_keys().account_address, miner_acc4.get_keys().account_address, tx_mine_4, block_reward_without_fee, TRANSACTION_VERSION_PRE_HF4); + construct_miner_tx(0, 0, 0, 0, 0, miner_acc4.get_keys().account_address, miner_acc4.get_keys().account_address, tx_mine_4, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4); transaction tx_mine_5; - construct_miner_tx(0, 0, 0, 0, 0, miner_acc5.get_keys().account_address, miner_acc5.get_keys().account_address, tx_mine_5, block_reward_without_fee, TRANSACTION_VERSION_PRE_HF4); + construct_miner_tx(0, 0, 0, 0, 0, miner_acc5.get_keys().account_address, miner_acc5.get_keys().account_address, tx_mine_5, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4); transaction tx_mine_6; - construct_miner_tx(0, 0, 0, 0, 0, miner_acc6.get_keys().account_address, miner_acc6.get_keys().account_address, tx_mine_6, block_reward_without_fee, TRANSACTION_VERSION_PRE_HF4); + construct_miner_tx(0, 0, 0, 0, 0, miner_acc6.get_keys().account_address, miner_acc6.get_keys().account_address, tx_mine_6, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4); //fill inputs entry typedef tx_source_entry::output_entry tx_output_entry; @@ -136,8 +137,9 @@ bool test_block_creation() bool r = get_account_address_from_str(adr, "ZxDLGBGXbjo5w51tJkvxEPHFRr7Xft4hf33N8EkJPndoGCqocQF1mzpZqYwXByx5gMbfQuPAAB9vj79EFR6Jwkgu1o3aMQPwJ"); CHECK_AND_ASSERT_MES(r, false, "failed to import"); uint64_t block_reward_without_fee = 0; + uint64_t block_reward = 0; block b; - r = construct_miner_tx(90, epee::misc_utils::median(szs), 3553616528562147, 33094, 10000000, adr, adr, b.miner_tx, block_reward_without_fee, TRANSACTION_VERSION_PRE_HF4); + r = construct_miner_tx(90, epee::misc_utils::median(szs), 3553616528562147, 33094, 10000000, adr, adr, b.miner_tx, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4); return r; } diff --git a/tests/core_tests/zarcanum_test.cpp b/tests/core_tests/zarcanum_test.cpp index ad014983..72dea5b4 100644 --- a/tests/core_tests/zarcanum_test.cpp +++ b/tests/core_tests/zarcanum_test.cpp @@ -812,8 +812,8 @@ bool zarcanum_block_with_txs::generate(std::vector& events) co // and Alice mines a PoS block with this tx -- so Alice is expected to receive the fee MAKE_NEXT_POS_BLOCK_TX1(events, blk_5, blk_4r, alice_acc, alice_stake_sources, tx_3); - // make sure Alice received both block reward and the fee - uint64_t mined_amount_2 = COIN + fee; + // make sure Alice received block reward but not received the fee + uint64_t mined_amount_2 = COIN /* + fee */; DO_CALLBACK_PARAMS(events, "check_balance", params_check_balance(ALICE_ACC_IDX, m_alice_balance + mined_amount_2, UINT64_MAX, mined_amount + mined_amount_2, 0, 0)); m_alice_balance += mined_amount_2;