-
Notifications
You must be signed in to change notification settings - Fork 38.7k
Add missing cs_main locks when accessing chainActive #11596
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
Conversation
src/validation.cpp
Outdated
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.
I think we can just add an AssertLockHeld(cs_main) to the top of this function -- this function only has two callers, both of which lock cs_main before calling.
EDIT: actually one of the callers does AssertLockHeld(cs_main).
src/wallet/wallet.cpp
Outdated
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.
I think we should just get rid of this assert. We can't guarantee chainActive height will not go down.
52b2f34 to
1c93531
Compare
promag
left a comment
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.
utACK.
src/wallet/wallet.cpp
Outdated
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.
Remove, all callers have cs_main locked, assert lock is held instead. Ping @ryanofsky as he says the goal is to removed recursive locks.
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.
@promag Thanks! Now fixed.
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.
@promag I'm getting an assertion failure when running test/functional/test_runner.py with your suggested patch applied. Does it pass for you? Reverting to previous version for now.
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.
I'll check.
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.
@promag See @TheBlueMatt's comment about cs_main locking in CWallet::CreateTransaction(…): #11596 (comment)
3371efe to
0ada52c
Compare
|
@practicalswift following #11596 (comment), I believe a7eb21a is the fix. |
0ada52c to
fdea0e2
Compare
src/rest.cpp
Outdated
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.
nit: care to do the serialization of bitmap/outs outside of cs_main (same below)?
src/wallet/wallet.cpp
Outdated
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.
Ugh, can we not add more cs_main requirements - if the goal is to resolve the chainActive.Height() issue only then please add the cs_main around just that, its not gonna hurt anything to not hold cs_main for the duration of this function, and we really should be trying to remove cs_main from this function, not go the other way.
17b7775 to
cd8ac3c
Compare
|
@TheBlueMatt Thanks for reviewing. Feedback addressed. |
src/wallet/rpcwallet.cpp
Outdated
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.
Please no. Can we instead add the locking in CreateTransaction itself? We need to be pushing locks down, especially when it comes to cs_main, not putting more locks in RPC functions.
cd8ac3c to
2e441c9
Compare
|
Reverting the patch suggested by @promag. The locking is now made down in |
|
utACK 2e441c91e7806e6ae781ae0b0aefea958079d15b |
src/rest.cpp
Outdated
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.
This isn't sufficient I think. We don't want to allow chainActive to change from when we get the results, to when we identify the chain they're for. So extract this info above in the first lock...
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.
Which first lock?
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.
@luke-jr Thanks for reviewing. Do you mean like this?
diff --git a/src/rest.cpp b/src/rest.cpp
index 0ed11e6..649059e 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -479,6 +479,8 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
std::string bitmapStringRepresentation;
std::vector<bool> hits;
bitmap.resize((vOutPoints.size() + 7) / 8);
+ int chainActiveHeight;
+ uint256 chainActiveTipBlockHash;
{
LOCK2(cs_main, mempool.cs);
@@ -503,6 +505,9 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
bitmapStringRepresentation.append(hit ? "1" : "0"); // form a binary string representation (human-readable for json output)
bitmap[i / 8] |= ((uint8_t)hit) << (i % 8);
}
+
+ chainActiveHeight = chainActive.Height();
+ chainActiveTipBlockHash = chainActive.Tip()->GetBlockHash();
}
switch (rf) {
@@ -510,11 +515,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
// serialize data
// use exact same output as mentioned in Bip64
CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION);
- {
- LOCK(cs_main);
- ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash();
- }
- ssGetUTXOResponse << bitmap << outs;
+ ssGetUTXOResponse << chainActiveHeight << chainActiveTipBlockHash << bitmap << outs;
std::string ssGetUTXOResponseString = ssGetUTXOResponse.str();
req->WriteHeader("Content-Type", "application/octet-stream");
@@ -524,11 +525,7 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
case RF_HEX: {
CDataStream ssGetUTXOResponse(SER_NETWORK, PROTOCOL_VERSION);
- {
- LOCK(cs_main);
- ssGetUTXOResponse << chainActive.Height() << chainActive.Tip()->GetBlockHash();
- }
- ssGetUTXOResponse << bitmap << outs;
+ ssGetUTXOResponse << chainActiveHeight << chainActiveTipBlockHash << bitmap << outs;
std::string strHex = HexStr(ssGetUTXOResponse.begin(), ssGetUTXOResponse.end()) + "\n";
req->WriteHeader("Content-Type", "text/plain");
@@ -541,11 +538,8 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
// pack in some essentials
// use more or less the same output as mentioned in Bip64
- {
- LOCK(cs_main);
- objGetUTXOResponse.push_back(Pair("chainHeight", chainActive.Height()));
- objGetUTXOResponse.push_back(Pair("chaintipHash", chainActive.Tip()->GetBlockHash().GetHex()));
- }
+ objGetUTXOResponse.push_back(Pair("chainHeight", chainActiveHeight));
+ objGetUTXOResponse.push_back(Pair("chaintipHash", chainActiveTipBlockHash.GetHex()));
objGetUTXOResponse.push_back(Pair("bitmap", bitmapStringRepresentation));
UniValue utxos(UniValue::VARR);
src/rest.cpp
Outdated
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.
Same
src/rest.cpp
Outdated
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.
Same.
2e441c9 to
9b3d094
Compare
|
Added commit 9b3d094894350933342b5e352785cfdd9f2d03fe addressing @luke-jr:s feedback. Please re-review :-) |
|
@practicalswift why did you rebase this? It makes reviewing something that was previously reviewed much more difficult. Mind squashing the two commits? There seems to be no reason to have them separate. |
luke-jr
left a comment
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.
utACK
The variable chainActive is guarded by the mutex cs_main. Github-Pull: bitcoin#11596 Rebased-From: 4786fe1a50c16381d723b5291938a615cc13a490
…n we identify the chain they're for Github-Pull: bitcoin#11596 Rebased-From: 9b3d094894350933342b5e352785cfdd9f2d03fe
9b3d094 to
0b9219e
Compare
|
Now squashed into one commit. Please re-review! :-) @TheBlueMatt The reason for the rebase was that I wanted to get rebased on top of 76ea17c (IIRC) in order to get the build to pass – I always compile with The reason for the two commits was to allow separate review for the latter commit in the case that I had misunderstood @luke-jr:s suggestion and needed to revert. |
0b9219e to
11256af
Compare
2d77055 to
cb21977
Compare
|
I've now reworked this PR and split it up in three commits:
Please re-review :-) /cc @sdaftuar @morcos @promag @TheBlueMatt @luke-jr @MarcoFalke |
cb21977 to
1090fa1
Compare
1090fa1 to
7abc218
Compare
7abc218 to
c04750f
Compare
|
Rebased! |
c04750f to
7d5e26e
Compare
|
Rebased! |
a40b60f to
f882f91
Compare
|
Rebased! Please re-review :-) |
TheBlueMatt
left a comment
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.
I guess this is somewhat duplicative with #11652, no? My review comments there apply here too.
src/wallet/test/wallet_tests.cpp
Outdated
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.
Can you just take both locks instead of adding a new scope and lots of diff lines? Its in a test, locks shouldn't matter much.
src/interfaces/wallet.cpp
Outdated
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.
a) annotations need to go in the header file, not the cpp file. b) I dont think we can put locks required in the interfaces file, as it may become a process boundary. The callee will have to take the lock itself.
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.
annotations need to go in the header file
This is ok, these are just internal functions (in an anonymous namespace) not shared or exposed in headers.
…not go down As noted by @Marcos in bitcoin#11596 (comment)
…at follow from "chainActive GUARDED_BY(cs_main)"
f882f91 to
d8c00bb
Compare
d8c00bb to
b0279a0
Compare
|
Rebased and updated. Please re-review :-) |
cs_mainlocks when accessingchainActive. (The variablechainActiveis guarded by the mutexcs_main.)GUARDED_BY+EXCLUSIVE_LOCKS_REQUIRED).