-
Notifications
You must be signed in to change notification settings - Fork 38.8k
log: print every script verification state change #33336
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
91ac64b
4fad4e9
9bc2985
f2ea6f0
6c13a38
45bd891
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2423,34 +2423,43 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state, | |
| return true; | ||
| } | ||
|
|
||
| bool fScriptChecks = true; | ||
| if (!m_chainman.AssumedValidBlock().IsNull()) { | ||
| const char* script_check_reason; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: Would be better to initialise to |
||
| if (m_chainman.AssumedValidBlock().IsNull()) { | ||
| script_check_reason = "assumevalid=0 (always verify)"; | ||
| } else { | ||
| constexpr int64_t TWO_WEEKS_IN_SECONDS{60 * 60 * 24 * 7 * 2}; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps: constexpr std::chrono::days TOO_RECENT_FOR_ASSUMEVALID{14};
...
} else if (GBPET(...) <= count_seconds(TOO_RECENT_FOR_ASSUME_VALID)) {
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't mind doing this in a separate PR, but here I have decided against it since it's not strictly related to the change and is in consensus code, see: #33336 (comment) |
||
| // We've been configured with the hash of a block which has been externally verified to have a valid history. | ||
| // A suitable default value is included with the software and updated from time to time. Because validity | ||
| // relative to a piece of software is an objective fact these defaults can be easily reviewed. | ||
| // This setting doesn't force the selection of any particular chain but makes validating some faster by | ||
| // effectively caching the result of part of the verification. | ||
| BlockMap::const_iterator it{m_blockman.m_block_index.find(m_chainman.AssumedValidBlock())}; | ||
| if (it != m_blockman.m_block_index.end()) { | ||
| if (it->second.GetAncestor(pindex->nHeight) == pindex && | ||
| m_chainman.m_best_header->GetAncestor(pindex->nHeight) == pindex && | ||
| m_chainman.m_best_header->nChainWork >= m_chainman.MinimumChainWork()) { | ||
| // This block is a member of the assumed verified chain and an ancestor of the best header. | ||
| // Script verification is skipped when connecting blocks under the | ||
| // assumevalid block. Assuming the assumevalid block is valid this | ||
| // is safe because block merkle hashes are still computed and checked, | ||
| // Of course, if an assumed valid block is invalid due to false scriptSigs | ||
| // this optimization would allow an invalid chain to be accepted. | ||
| // The equivalent time check discourages hash power from extorting the network via DOS attack | ||
| // into accepting an invalid block through telling users they must manually set assumevalid. | ||
| // Requiring a software change or burying the invalid block, regardless of the setting, makes | ||
| // it hard to hide the implication of the demand. This also avoids having release candidates | ||
| // that are hardly doing any signature verification at all in testing without having to | ||
| // artificially set the default assumed verified block further back. | ||
| // The test against the minimum chain work prevents the skipping when denied access to any chain at | ||
| // least as good as the expected chain. | ||
| fScriptChecks = (GetBlockProofEquivalentTime(*m_chainman.m_best_header, *pindex, *m_chainman.m_best_header, params.GetConsensus()) <= 60 * 60 * 24 * 7 * 2); | ||
| } | ||
| if (it == m_blockman.m_block_index.end()) { | ||
| script_check_reason = "assumevalid hash not in headers"; | ||
| } else if (it->second.GetAncestor(pindex->nHeight) != pindex) { | ||
| script_check_reason = (pindex->nHeight > it->second.nHeight) ? "block height above assumevalid height" : "block not in assumevalid chain"; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: Better as an |
||
| } else if (m_chainman.m_best_header->GetAncestor(pindex->nHeight) != pindex) { | ||
| script_check_reason = "block not in best header chain"; | ||
| } else if (m_chainman.m_best_header->nChainWork < m_chainman.MinimumChainWork()) { | ||
| script_check_reason = "best header chainwork below minimumchainwork"; | ||
| } else if (GetBlockProofEquivalentTime(*m_chainman.m_best_header, *pindex, *m_chainman.m_best_header, params.GetConsensus()) <= TWO_WEEKS_IN_SECONDS) { | ||
| script_check_reason = "block too recent relative to best header"; | ||
| } else { | ||
| // This block is a member of the assumed verified chain and an ancestor of the best header. | ||
| // Script verification is skipped when connecting blocks under the | ||
| // assumevalid block. Assuming the assumevalid block is valid this | ||
| // is safe because block merkle hashes are still computed and checked, | ||
| // Of course, if an assumed valid block is invalid due to false scriptSigs | ||
| // this optimization would allow an invalid chain to be accepted. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Separate text with a blank line rather than indenting?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The original message contained these indentations - except in a very few cases that I adjusted for consistency. It seemed simpler to me to unify the text that way - otherwise I would have rewritten it completely since I don't particularly like the way it describes the situation. |
||
| // The equivalent time check discourages hash power from extorting the network via DOS attack | ||
| // into accepting an invalid block through telling users they must manually set assumevalid. | ||
| // Requiring a software change or burying the invalid block, regardless of the setting, makes | ||
| // it hard to hide the implication of the demand. This also avoids having release candidates | ||
| // that are hardly doing any signature verification at all in testing without having to | ||
| // artificially set the default assumed verified block further back. | ||
| // The test against the minimum chain work prevents the skipping when denied access to any chain at | ||
| // least as good as the expected chain. | ||
| script_check_reason = nullptr; | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -2563,9 +2572,16 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state, | |
| Ticks<SecondsDouble>(m_chainman.time_forks), | ||
| Ticks<MillisecondsDouble>(m_chainman.time_forks) / m_chainman.num_blocks_total); | ||
|
|
||
| if (fScriptChecks != m_prev_script_checks_logged && GetRole() == ChainstateRole::NORMAL) { | ||
| LogInfo("%s signature validations at block #%d (%s).", fScriptChecks ? "Enabling" : "Disabling", pindex->nHeight, block_hash.ToString()); | ||
| m_prev_script_checks_logged = fScriptChecks; | ||
| const bool fScriptChecks{!!script_check_reason}; | ||
| if (script_check_reason != m_last_script_check_reason_logged && GetRole() == ChainstateRole::NORMAL) { | ||
| if (fScriptChecks) { | ||
| LogInfo("Enabling script verification at block #%d (%s): %s.", | ||
| pindex->nHeight, block_hash.ToString(), script_check_reason); | ||
| } else { | ||
| LogInfo("Disabling script verification at block #%d (%s).", | ||
| pindex->nHeight, block_hash.ToString()); | ||
| } | ||
| m_last_script_check_reason_logged = script_check_reason; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. consider setting
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean to only log enabled/disabled changes, but not enabled-after-assumevalid/enabled-no-burried changes? This was also deliberate to show the exact reason so that users understand the why and not just whether it's enabled.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe the parent comment means to set a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I understood that, but that will be a behavior change, since currently after
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand why you think it's a behavior change. It has nothing to do with logging. Add this on line 2585:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Ah, you mean to keep lines
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done, thanks |
||
| } | ||
|
|
||
| CBlockUndo blockundo; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.