From d7f6bca2c2fbc083635a4305a5b5bf5f9053cd34 Mon Sep 17 00:00:00 2001 From: Azat Nizametdinov Date: Mon, 13 May 2019 16:52:07 +0200 Subject: [PATCH] Validate number of outputs in coinbase transaction Signed-off-by: Azat Nizametdinov --- src/staking/block_reward_validator.cpp | 6 ++++++ .../staking/block_reward_validator_tests.cpp | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/staking/block_reward_validator.cpp b/src/staking/block_reward_validator.cpp index 6c41c863b2..972e627161 100644 --- a/src/staking/block_reward_validator.cpp +++ b/src/staking/block_reward_validator.cpp @@ -29,6 +29,12 @@ class BlockRewardValidatorImpl : public BlockRewardValidator { CAmount total_reward = fees + m_behavior->CalculateBlockReward(index.nHeight); std::size_t num_reward_outputs = 1; + if (coinbase_tx.vout.size() < num_reward_outputs) { + return state.DoS(100, + error("%s: too few coinbase outputs expected at least %d actual %d", __func__, + num_reward_outputs, coinbase_tx.vout.size()), + REJECT_INVALID, "bad-cb-too-few-outputs"); + } CAmount output_amount = coinbase_tx.GetValueOut(); if (output_amount - input_amount > total_reward) { diff --git a/src/test/staking/block_reward_validator_tests.cpp b/src/test/staking/block_reward_validator_tests.cpp index 1c44d26933..6718a28461 100644 --- a/src/test/staking/block_reward_validator_tests.cpp +++ b/src/test/staking/block_reward_validator_tests.cpp @@ -103,6 +103,22 @@ BOOST_AUTO_TEST_CASE(total_output_is_too_large) { test_invalid_outputs({f.immediate_reward + fees, input_amount + 1}); } +BOOST_AUTO_TEST_CASE(no_outputs) { + Fixture f; + const auto validator = f.GetBlockRewardValidator(); + + const CAmount input_amount = 11 * UNIT; + const CAmount fees = UNIT / 2; + CTransaction tx = f.MakeCoinbaseTx({}); + CValidationState validation_state; + + const bool result = validator->CheckBlockRewards(tx, validation_state, f.block, input_amount, fees); + BOOST_CHECK(!result); + BOOST_CHECK(!validation_state.IsValid()); + BOOST_CHECK_EQUAL(validation_state.GetRejectCode(), REJECT_INVALID); + BOOST_CHECK_EQUAL(validation_state.GetRejectReason(), "bad-cb-too-few-outputs"); +} + BOOST_AUTO_TEST_CASE(total_output_is_too_small) { Fixture f; const auto validator = f.GetBlockRewardValidator();