-
Notifications
You must be signed in to change notification settings - Fork 37.7k
refactor: inline constant return values from dbwrapper
write methods
#33042
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
base: master
Are you sure you want to change the base?
Conversation
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code Coverage & BenchmarksFor details see: https://corecheck.dev/bitcoin/bitcoin/pulls/33042. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
Is this refactor also part of a series to align the |
We could go the other way as well, enabling writes to only return a boolean and handle them everywhere. |
Looks like this was introduced in 421218d, I guess because it was less verbose. How verbose would it be to pass it up and check it everywhere? Also, |
With diff --git a/src/node/blockstorage.h b/src/node/blockstorage.h
--- a/src/node/blockstorage.h (revision 09f004bd9fecbee2216ffb6b7bb787d9ec4f0362)
+++ b/src/node/blockstorage.h (date 1753416740263)
@@ -52,14 +52,14 @@
{
public:
using CDBWrapper::CDBWrapper;
- bool WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*>>& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo);
- bool ReadBlockFileInfo(int nFile, CBlockFileInfo& info);
- bool ReadLastBlockFile(int& nFile);
- bool WriteReindexing(bool fReindexing);
+ [[nodiscard]] bool WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*>>& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo);
+ [[nodiscard]] bool ReadBlockFileInfo(int nFile, CBlockFileInfo& info);
+ [[nodiscard]] bool ReadLastBlockFile(int& nFile);
+ [[nodiscard]] bool WriteReindexing(bool fReindexing);
void ReadReindexing(bool& fReindexing);
- bool WriteFlag(const std::string& name, bool fValue);
- bool ReadFlag(const std::string& name, bool& fValue);
- bool LoadBlockIndexGuts(const Consensus::Params& consensusParams, std::function<CBlockIndex*(const uint256&)> insertBlockIndex, const util::SignalInterrupt& interrupt)
+ [[nodiscard]] bool WriteFlag(const std::string& name, bool fValue);
+ [[nodiscard]] bool ReadFlag(const std::string& name, bool& fValue);
+ [[nodiscard]] bool LoadBlockIndexGuts(const Consensus::Params& consensusParams, std::function<CBlockIndex*(const uint256&)> insertBlockIndex, const util::SignalInterrupt& interrupt)
EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
};
} // namespace kernel
and diff --git a/src/dbwrapper.h b/src/dbwrapper.h
--- a/src/dbwrapper.h (revision 09f004bd9fecbee2216ffb6b7bb787d9ec4f0362)
+++ b/src/dbwrapper.h (date 1753415399087)
@@ -210,7 +210,7 @@
CDBWrapper& operator=(const CDBWrapper&) = delete;
template <typename K, typename V>
- bool Read(const K& key, V& value) const
+ [[nodiscard]] bool Read(const K& key, V& value) const
{
DataStream ssKey{};
ssKey.reserve(DBWRAPPER_PREALLOC_KEY_SIZE);
@@ -230,7 +230,7 @@
}
template <typename K, typename V>
- bool Write(const K& key, const V& value, bool fSync = false)
+ [[nodiscard]] bool Write(const K& key, const V& value, bool fSync = false)
{
CDBBatch batch(*this);
batch.Write(key, value);
@@ -255,14 +255,14 @@
}
template <typename K>
- bool Erase(const K& key, bool fSync = false)
+ [[nodiscard]] bool Erase(const K& key, bool fSync = false)
{
CDBBatch batch(*this);
batch.Erase(key);
return WriteBatch(batch, fSync);
}
- bool WriteBatch(CDBBatch& batch, bool fSync = false);
+ [[nodiscard]] bool WriteBatch(CDBBatch& batch, bool fSync = false);
// Get an estimate of LevelDB memory usage (in bytes).
size_t DynamicMemoryUsage() const; and handling all of the calls, but I'm getting failures all over the place, mostly because
Checking all index usages of Also, it seem the build passes with: void CDBWrapper::WriteBatch(CDBBatch& batch, bool fSync)
{
// ...
leveldb::Status status = DBContext().pdb->Write(...);
if (!status.ok()) { assert(false); } // instead of HandleError(status);
if (!status.ok()) { } // alternatively, this also passes So we don't really have coverage for errors, even though |
Yeah, I'd presume you'd have to use
I tried that yesterday, and an error in the index code ( |
I think the question boils down to: How much UX do we want to provide for data corruption or internal bugs? A valid answer could be: None. In that case you can just use Other valid answers are: Best-effort (use |
Concept ACK Implemented the same thing some time ago TheCharlatan@de7e3a9#diff-ac5fbeb5de6f28370bc348a579fc465fe7f7b91df0e0483c6edbf10273278c0d. |
The IRC meeting contained feedback on the overall direction:
|
`WriteBatch` can only ever return `true` - its errors are handled by throwing a `throw dbwrapper_error` instead. The boolean return value is quite confusing, especially since it's symmetric with `CDBWrapper::Read`, which catches the exceptions and returns a boolean instead. We're removing the constant return value and inlining `true` for its usages.
…ockTreeDB::WriteReindexing` Did both in this commit, since the return value of `WriteReindexing` was ignored anyway - which existed only because of the constant `Erase` being called
…c` and `BlockManager::WriteBlockIndexDB` and `BlockTreeDB::WriteFlag`
0c7096f
to
743abbc
Compare
Rebased after #33116, ready for review again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So after reading the feedback from the IRC discussion, in my opinion the PR should be fine. (Not sure about the dead code part and if there is still the need to delete some dead code but that can be a follow up PR )
This PR changes the signature of the function to set the return value to void
. This to reflect the inner workings of the function better. The function does not return a relevant bool but always returns true. This is now corrected.
ACK 743abbc
- code review ✅
- build & tested ✅
Related to #31144 (comment)
Summary
WriteBatch
always returnstrue
- the errors are handled by throwingdbwrapper_error
instead.Context
This boolean return value of the
Write
methods is confusing because it's inconsistent withCDBWrapper::Read
, which catches exceptions and returns a boolean to indicate success/failure. It's bad thatRead
returns andWrite
throws - but it's a lot worse thatWrite
advertises a return value when it actually communicates errors through exceptions.Solution
This PR removes the constant return values from write methods and inlines
true
at their call sites. Many upstream methods had boolean return values only because they were propagating these constants - those have been cleaned up as well.Methods that returned a constant
true
value that now returnvoid
:CDBWrapper::WriteBatch
,CDBWrapper::Write
,CDBWrapper::Erase
TxIndex::DB::WriteTxs
BlockTreeDB::WriteReindexing
,BlockTreeDB::WriteBatchSync
,BlockTreeDB::WriteFlag
BlockManager::WriteBlockIndexDB
Note
CCoinsView::BatchWrite
(and transitivelyCCoinsViewCache::Flush
&CCoinsViewCache::Sync
) were intentionally not changed here. While all implementations returntrue
, the baseCCoinsView::BatchWrite
returnsfalse
. Changing this would causecoins_view
tests to fail with:We can fix that in a follow-up PR.