diff --git a/src/validation.cpp b/src/validation.cpp index 9953aea28a0..85b00858ac4 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3644,6 +3644,26 @@ bool HasValidProofOfWork(const std::vector& headers, const Consens [&](const auto& header) { return CheckProofOfWork(header.GetHash(), header.nBits, consensusParams);}); } +bool IsBlockMutated(const CBlock& block, bool check_witness_root) +{ + BlockValidationState state; + if (!CheckMerkleRoot(block, state)) { + LogPrint(BCLog::VALIDATION, "Block mutated: %s\n", state.ToString()); + return true; + } + + if (block.vtx.empty() || !block.vtx[0]->IsCoinBase()) { + return false; + } + + if (!CheckWitnessMalleation(block, check_witness_root, state)) { + LogPrint(BCLog::VALIDATION, "Block mutated: %s\n", state.ToString()); + return true; + } + + return false; +} + arith_uint256 CalculateHeadersWork(const std::vector& headers) { arith_uint256 total_work{0}; diff --git a/src/validation.h b/src/validation.h index fd0e2115f7d..b6e2e66a449 100644 --- a/src/validation.h +++ b/src/validation.h @@ -352,6 +352,9 @@ bool TestBlockValidity(BlockValidationState& state, /** Check with the proof of work on each blockheader matches the value in nBits */ bool HasValidProofOfWork(const std::vector& headers, const Consensus::Params& consensusParams); +/** Check if a block has been mutated (with respect to its merkle root and witness commitments). */ +bool IsBlockMutated(const CBlock& block, bool check_witness_root); + /** Return the sum of the work on a given set of headers */ arith_uint256 CalculateHeadersWork(const std::vector& headers);