diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index 87bb4e15a..51912ce58 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -173,6 +173,7 @@ #define HF_VERSION_REJECT_SIGS_IN_COINBASE 12 #define HF_VERSION_ENFORCE_MIN_AGE 12 #define HF_VERSION_EFFECTIVE_SHORT_TERM_MEDIAN_IN_PENALTY 12 +#define HF_VERSION_EXACT_COINBASE 13 #define PER_KB_FEE_QUANTIZATION_DECIMALS 8 diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 7851b0f6a..dafc44803 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1392,8 +1392,8 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl 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; } - // From hard fork 2, we allow a miner to claim less block reward than is allowed, in case a miner wants less dust - if (version < 2) + // From hard fork 2 till 12, we allow a miner to claim less block reward than is allowed, in case a miner wants less dust + if (version < 2 || version >= HF_VERSION_EXACT_COINBASE) { if(base_reward + fee != money_in_use) { diff --git a/tests/core_tests/block_validation.cpp b/tests/core_tests/block_validation.cpp index 10b1b9af4..fb8ddbe11 100644 --- a/tests/core_tests/block_validation.cpp +++ b/tests/core_tests/block_validation.cpp @@ -655,3 +655,19 @@ bool gen_block_late_v1_coinbase_tx::generate(std::vector& even return true; } + +bool gen_block_low_coinbase::generate(std::vector& events) const +{ + BLOCK_VALIDATION_INIT_GENERATE(); + + block blk_1; + std::vector block_weights; + generator.construct_block(blk_1, cryptonote::get_block_height(blk_0) + 1, cryptonote::get_block_hash(blk_0), + miner_account, blk_0.timestamp + DIFFICULTY_TARGET_V2, COIN + generator.get_already_generated_coins(cryptonote::get_block_hash(blk_0)), + block_weights, {}, HF_VERSION_EXACT_COINBASE); + events.push_back(blk_1); + + DO_CALLBACK(events, "check_block_purged"); + + return true; +} diff --git a/tests/core_tests/block_validation.h b/tests/core_tests/block_validation.h index 39eba0829..0dd4e145c 100644 --- a/tests/core_tests/block_validation.h +++ b/tests/core_tests/block_validation.h @@ -218,3 +218,15 @@ struct get_test_options { hard_forks, 0 }; }; + +struct gen_block_low_coinbase : public gen_block_verification_base<1> +{ + bool generate(std::vector& events) const; +}; +template<> +struct get_test_options { + const std::pair hard_forks[3] = {std::make_pair(1, 0), std::make_pair(HF_VERSION_EXACT_COINBASE, 1), std::make_pair(0, 0)}; + const cryptonote::test_options test_options = { + hard_forks, 0 + }; +}; diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index 38382b95f..9895d4814 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -264,6 +264,8 @@ int main(int argc, char* argv[]) GENERATE_AND_PLAY(gen_bp_tx_invalid_wrong_amount); GENERATE_AND_PLAY(gen_bp_tx_invalid_borromean_type); + GENERATE_AND_PLAY(gen_block_low_coinbase); + el::Level level = (failed_tests.empty() ? el::Level::Info : el::Level::Error); if (!list_tests) {