rpc: Remove cs_main lock from blockToJSON and blockheaderToJSON #12151

pull promag wants to merge 3 commits into bitcoin:master from promag:2018-01-blocktojson changing 4 files +37 −48
  1. promag commented at 1:19 pm on January 11, 2018: member

    Motivated by #11913 (review), this pull makes blockToJSON and blockheaderToJSON free of cs_main locks.

    Locking cs_main was required to access chainActive in order to check if the block was in the chain and to retrieve the next block index.

    With the this approach, CBlockIndex::GetAncestor() is used in a way to check if the block belongs to the specified chain tip and, at the same time, get the next block index.

  2. promag force-pushed on Jan 11, 2018
  3. promag force-pushed on Jan 11, 2018
  4. promag force-pushed on Jan 11, 2018
  5. promag force-pushed on Jan 11, 2018
  6. in src/rpc/blockchain.cpp:84 in f88df2e9c9 outdated
    77@@ -78,20 +78,22 @@ double GetDifficulty(const CChain& chain, const CBlockIndex* blockindex)
    78     return dDiff;
    79 }
    80 
    81-double GetDifficulty(const CBlockIndex* blockindex)
    82+static int ComputeBlockConfirmations(const CBlockIndex* tip, const CBlockIndex* blockindex, const CBlockIndex*& next)
    83 {
    84-    return GetDifficulty(chainActive, blockindex);
    85+    next = tip->GetAncestor(blockindex->nHeight + 1);
    86+    if (next && next->pprev == blockindex) {
    


    TheBlueMatt commented at 5:46 pm on January 11, 2018:
    Why? You can just do a GetAncestor for blockindex->nHeight here, no?

    promag commented at 6:16 pm on January 11, 2018:
    This way you get next of blockindex.

    TheBlueMatt commented at 6:18 pm on January 11, 2018:
    Ohoh, sorry, missed its use in blockheaderToJSON.

    ryanofsky commented at 11:01 pm on February 5, 2018:
    This confused me for a minute too. Maybe could rename function to something like ComputeNextBlockAndDepth to mention the next part.

    promag commented at 11:10 pm on February 5, 2018:
    Can do, WDYT about returning std::pair<int, const CBlockIndex*>?

    promag commented at 11:11 pm on February 5, 2018:
    I can add a comment there too explaning the height + 1 and ->pprev == blockindex.

    promag commented at 4:23 pm on February 26, 2018:
    Renamed to ComputeNextBlockAndDepth as per @ryanofsky suggestion.
  7. in src/rpc/blockchain.cpp:1249 in f88df2e9c9 outdated
    1181@@ -1185,20 +1182,21 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
    1182 
    1183     LOCK(cs_main);
    1184 
    1185+    const CBlockIndex* tip = chainActive.Tip();
    


    TheBlueMatt commented at 5:48 pm on January 11, 2018:
    No need to change these unless you’re gonna actually kill the cs_main held for the whole time, I’d think, no (and little reason to, its not like its being held for an extended period)?

    promag commented at 6:18 pm on January 11, 2018:
    This moves up tip variable declared below.
  8. TheBlueMatt commented at 5:49 pm on January 11, 2018: member
    Generally wouldn’t bother too much reducing cs_main scope when its really a trivial amount of time running with cs_main held, though I agree in the context of #11913 it makes sense to not lock cs_main and then unlock, then re-lock it there.
  9. promag commented at 6:19 pm on January 11, 2018: member
    Best reviewed commit by commit
  10. in src/rpc/blockchain.cpp:106 in f88df2e9c9 outdated
    102@@ -101,26 +103,22 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex)
    103     result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
    104     result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce));
    105     result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits)));
    106-    result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
    107+    result.push_back(Pair("difficulty", GetDifficulty(chainActive.Tip(), blockindex)));
    


    jimpo commented at 9:51 pm on January 11, 2018:
    tip instead of chainActive.Tip()?
  11. in src/rpc/blockchain.cpp:147 in f88df2e9c9 outdated
    143@@ -146,12 +144,11 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx
    144     result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast()));
    145     result.push_back(Pair("nonce", (uint64_t)block.nNonce));
    146     result.push_back(Pair("bits", strprintf("%08x", block.nBits)));
    147-    result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
    148+    result.push_back(Pair("difficulty", GetDifficulty(chainActive.Tip(), blockindex)));
    


    jimpo commented at 9:52 pm on January 11, 2018:
    tip instead of chainActive.Tip()?
  12. in src/rpc/blockchain.cpp:85 in f88df2e9c9 outdated
    82+static int ComputeBlockConfirmations(const CBlockIndex* tip, const CBlockIndex* blockindex, const CBlockIndex*& next)
    83 {
    84-    return GetDifficulty(chainActive, blockindex);
    85+    next = tip->GetAncestor(blockindex->nHeight + 1);
    86+    if (next && next->pprev == blockindex) {
    87+        return tip->nHeight - blockindex->nHeight;
    


    jimpo commented at 9:57 pm on January 11, 2018:
    Should be +1 I believe?
  13. in src/rpc/blockchain.cpp:88 in f88df2e9c9 outdated
    85+    next = tip->GetAncestor(blockindex->nHeight + 1);
    86+    if (next && next->pprev == blockindex) {
    87+        return tip->nHeight - blockindex->nHeight;
    88+    }
    89+    next = nullptr;
    90+    return blockindex == tip ? 0 : -1;
    


    jimpo commented at 9:57 pm on January 11, 2018:
    Should be ? 1 : -1. Blocks that are the chain tip have 1 confirmation.
  14. promag force-pushed on Jan 11, 2018
  15. in src/rest.cpp:246 in 8ca09810e1 outdated
    242@@ -242,11 +243,7 @@ static bool rest_block(HTTPRequest* req,
    243     }
    244 
    245     case RF_JSON: {
    246-        UniValue objBlock;
    247-        {
    248-            LOCK(cs_main);
    249-            objBlock = blockToJSON(block, pblockindex, showTxDetails);
    250-        }
    251+        UniValue objBlock = std::move(blockToJSON(block, pblockindex, tip, showTxDetails));
    


    promag commented at 10:41 pm on January 11, 2018:
    Wrong order, should be tip, pblockindex.
  16. in src/rpc/blockchain.cpp:785 in 8ca09810e1 outdated
    781@@ -785,7 +782,7 @@ UniValue getblock(const JSONRPCRequest& request)
    782         return strHex;
    783     }
    784 
    785-    return blockToJSON(block, pblockindex, verbosity >= 2);
    786+    return blockToJSON(block, pblockindex, chainActive.Tip(), verbosity >= 2);
    


    promag commented at 10:41 pm on January 11, 2018:
    Same.
  17. promag commented at 10:42 pm on January 11, 2018: member
    Changed the order in the signature and forgot to change callers.
  18. promag force-pushed on Jan 11, 2018
  19. promag commented at 10:52 pm on January 11, 2018: member
    Fixed @TheBlueMatt and @jimpo comments, thanks.
  20. fanquake added the label RPC/REST/ZMQ on Jan 13, 2018
  21. ryanofsky commented at 11:02 pm on February 5, 2018: member
    utACK f6d175ddc97a0d2b2614b44ddb9efbebf8d6eec5
  22. promag force-pushed on Feb 26, 2018
  23. promag force-pushed on Feb 26, 2018
  24. promag commented at 4:25 pm on February 26, 2018: member

    Rebased mainly due to recent change from push_back(Pair()) to pushKV().

    Also reworded to replace prefix [rpc] to rpc: as per @laanwj suggestion.

  25. MarcoFalke commented at 1:13 am on March 19, 2018: member
    Needs rebase if still relevant
  26. in src/rest.cpp:246 in 2925d3be3f outdated
    242@@ -242,11 +243,7 @@ static bool rest_block(HTTPRequest* req,
    243     }
    244 
    245     case RF_JSON: {
    246-        UniValue objBlock;
    247-        {
    248-            LOCK(cs_main);
    249-            objBlock = blockToJSON(block, pblockindex, showTxDetails);
    250-        }
    251+        UniValue objBlock = std::move(blockToJSON(block, tip, pblockindex, showTxDetails));
    


    dcousens commented at 2:49 am on March 19, 2018:
    Does return-value optimization not capture this?

    promag commented at 1:51 pm on March 19, 2018:
    I think you are correct.
  27. promag force-pushed on Mar 19, 2018
  28. promag commented at 1:53 pm on March 19, 2018: member

    Rebased. @MarcoFalke like @TheBlueMatt said above:

    in the context of #11913 it makes sense to not lock cs_main and then unlock, then re-lock it there.

    I’d say at least let’s wait for that.

  29. jnewbery commented at 9:56 pm on April 3, 2018: member
    needs rebase
  30. promag commented at 10:13 pm on April 3, 2018: member
    Rebased.
  31. promag force-pushed on Apr 3, 2018
  32. in src/rest.cpp:246 in 77d51a6810 outdated
    242@@ -242,11 +243,7 @@ static bool rest_block(HTTPRequest* req,
    243     }
    244 
    245     case RetFormat::JSON: {
    246-        UniValue objBlock;
    247-        {
    248-            LOCK(cs_main);
    249-            objBlock = blockToJSON(block, pblockindex, showTxDetails);
    250-        }
    251+      UniValue objBlock = blockToJSON(block, tip, pblockindex, showTxDetails);
    


    ryanofsky commented at 6:37 pm on April 4, 2018:
    Indentation isn’t consistent this line.

    promag commented at 10:38 pm on April 4, 2018:
    Sorry, indentation fixed.
  33. ryanofsky commented at 6:38 pm on April 4, 2018: member
    utACK 77d51a68108e282856d9894d41e8a600dba78dd8. No changes since last review other than rebase and removing std::move.
  34. promag force-pushed on Apr 4, 2018
  35. ryanofsky commented at 9:26 pm on April 16, 2018: member
    utACK e20f745d9b279de9e43994505731658f0f3582fa, just whitespace fix since last review
  36. in src/rpc/blockchain.cpp:54 in 8e2dec70dc outdated
    50@@ -51,14 +51,14 @@ extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue&
    51 /* Calculate the difficulty for a given block index,
    52  * or the block index of the given chain.
    53  */
    54-double GetDifficulty(const CChain& chain, const CBlockIndex* blockindex)
    55+double GetDifficulty(const CBlockIndex* tip, const CBlockIndex* blockindex)
    


    jimpo commented at 11:25 pm on May 17, 2018:

    commit: rpc: Specify chain tip instead of chain in GetDifficulty

    I don’t think this is really necessary. Would rather just inline GetDifficulty(blockindex ? blockindex : chainActive.Tip()) at the few call sites if blockindex may be null.

    I don’t actually see any instances in this file where blockindex might be nullptr.


    promag commented at 0:11 am on May 18, 2018:

    Below there is the test

    0// Verify that difficulty is 1.0 for a null chain tip.
    1BOOST_AUTO_TEST_CASE(get_difficulty_for_null_tip)
    2{
    3    double difficulty = GetDifficulty(nullptr, nullptr);
    4    RejectDifficultyMismatch(difficulty, 1.0);
    5}
    

    Do you agree changing to

    0// Verify that difficulty is 1.0 for a null block index.
    1BOOST_AUTO_TEST_CASE(get_difficulty_for_null_block)
    2{
    3    double difficulty = GetDifficulty(nullptr);
    4    RejectDifficultyMismatch(difficulty, 1.0);
    5}
    

    or should change the return value?

    If you don’t mind I would rather keep the existing behaviour and discuss this elsewhere.


    jimpo commented at 0:17 am on May 18, 2018:
    Yes, I am proposing changing the behavior so that if null is passed it, it returns 1. I think that makes the most sense in the context of this change because you want are removing the dependence of this function on chainActive. Given that you are updating every invocation, this seems like the right time to make the change I am proposing.

  37. jimpo commented at 11:45 pm on May 17, 2018: contributor
    I think you can stop passing tip to GetDifficulty in most places.
  38. promag force-pushed on May 18, 2018
  39. MarcoFalke renamed this:
    Remove cs_main lock from blockToJSON and blockheaderToJSON
    rpc: Remove cs_main lock from blockToJSON and blockheaderToJSON
    on Jun 5, 2018
  40. MarcoFalke added the label Refactoring on Jun 5, 2018
  41. MarcoFalke commented at 10:35 pm on June 5, 2018: member
    Needs rebase
  42. MarcoFalke added the label Needs rebase on Jun 6, 2018
  43. promag force-pushed on Jun 10, 2018
  44. promag commented at 8:34 pm on June 10, 2018: member
    Rebased.
  45. DrahtBot removed the label Needs rebase on Jun 11, 2018
  46. in src/rpc/blockchain.h:19 in 124b71774a outdated
     9@@ -10,8 +10,7 @@ class CBlockIndex;
    10 class UniValue;
    11 
    12 /**
    13- * Get the difficulty of the net wrt to the given block index, or the chain tip if
    14- * not provided.
    15+ * Get the difficulty of the net wrt to the given block index.
    


    fanquake commented at 1:03 pm on July 8, 2018:
    From #13602: Can you drop the “to” here.

    promag commented at 5:36 pm on July 8, 2018:
    Sure!
  47. promag force-pushed on Jul 8, 2018
  48. in src/rpc/blockchain.cpp:61 in ceac7845ba outdated
    51@@ -52,10 +52,7 @@ static CUpdatedBlock latestblock;
    52  */
    53 double GetDifficulty(const CBlockIndex* blockindex)
    54 {
    55-    if (blockindex == nullptr)
    56-    {
    57-        return 1.0;
    58-    }
    59+    assert(blockindex);
    


    Empact commented at 8:34 am on August 11, 2018:

    promag commented at 5:05 pm on January 3, 2019:
    I believe chainActive.Tip() is always non null.
  49. promag commented at 0:43 am on August 12, 2018: member
    Now related to #13903.
  50. DrahtBot added the label Needs rebase on Sep 4, 2018
  51. rpc: Fix SoftForkMajorityDesc and SoftForkDesc signatures 54dc13b6a2
  52. rpc: Specify chain tip instead of chain in GetDifficulty 343b98cbcd
  53. rpc: Remove cs_main lock from blockToJSON and blockHeaderToJSON b9f226b41f
  54. promag force-pushed on Sep 9, 2018
  55. DrahtBot removed the label Needs rebase on Sep 9, 2018
  56. ryanofsky commented at 8:40 pm on September 14, 2018: member
    utACK b9f226b41f989f5c07fe57801701a39c14a6e173 only change since previous review is simplifying GetDifficulty in the second commit.
  57. in src/rpc/blockchain.cpp:61 in 343b98cbcd outdated
    57@@ -58,10 +58,7 @@ static CUpdatedBlock latestblock;
    58  */
    59 double GetDifficulty(const CBlockIndex* blockindex)
    60 {
    61-    if (blockindex == nullptr)
    62-    {
    63-        return 1.0;
    64-    }
    65+    assert(blockindex);
    


    MarcoFalke commented at 10:05 pm on September 14, 2018:
    In rpc code, assert should be replaced with throw JSONRPCError?

    promag commented at 5:06 pm on January 3, 2019:
    I don’t think this is a usage error, should be a programatic error?

    MarcoFalke commented at 5:12 pm on January 3, 2019:
    I guess you could avoid the assert by passing in a const reference?

    promag commented at 5:18 pm on January 3, 2019:
    Sure but out of scope here and I’m happy to submit that refactor in a separate PR.
  58. DrahtBot commented at 1:27 pm on September 21, 2018: member

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Conflicts

    No conflicts as of last run.

  59. MarcoFalke commented at 5:10 pm on January 3, 2019: member
    utACK b9f226b41f989f5c07fe57801701a39c14a6e173
  60. MarcoFalke referenced this in commit f7e182a973 on Jan 4, 2019
  61. MarcoFalke merged this on Jan 4, 2019
  62. MarcoFalke closed this on Jan 4, 2019

  63. promag deleted the branch on Jan 4, 2019
  64. LarryRuane referenced this in commit 39a28fdc03 on Apr 29, 2021
  65. LarryRuane referenced this in commit 1c0aed8bdb on Apr 29, 2021
  66. LarryRuane referenced this in commit 7b71d3e522 on Apr 29, 2021
  67. LarryRuane referenced this in commit e346ed3563 on Jun 1, 2021
  68. LarryRuane referenced this in commit 2bd3a2ef26 on Jun 1, 2021
  69. LarryRuane referenced this in commit 6bcb6fdf2f on Jun 1, 2021
  70. Munkybooty referenced this in commit d1d56bd940 on Aug 14, 2021
  71. Munkybooty referenced this in commit 521d1bc0c3 on Aug 24, 2021
  72. Munkybooty referenced this in commit 9ae8784746 on Aug 24, 2021
  73. UdjinM6 referenced this in commit 2234071ec0 on Aug 24, 2021
  74. Munkybooty referenced this in commit 31c5651a7d on Aug 24, 2021
  75. Munkybooty referenced this in commit 9436caf89a on Aug 24, 2021
  76. DrahtBot locked this on Dec 16, 2021

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-12-18 21:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me