Repository: bitcoin/bitcoin
File: src/rpc/blockchain.cpp (C++)

Code before:
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
    uint256 hash(ParseHashV(request.params[0], "blockhash"));

    int verbosity{ParseVerbosity(request.params[1], /*default_verbosity=*/1, /*allow_bool=*/true)};

    const CBlockIndex* pblockindex;
    const CBlockIndex* tip;
    ChainstateManager& chainman = EnsureAnyChainman(request.context);
    {
        LOCK(cs_main);
        pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
        tip = chainman.ActiveChain().Tip();

        if (!pblockindex) {
            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
        }
    }

    const std::vector<std::byte> block_data{GetRawBlockChecked(chainman.m_blockman, *pblockindex)};

    if (verbosity <= 0) {
        return HexStr(block_data);
    }

    SpanReader block_stream{block_data};
    CBlock block{};
    block_stream >> TX_WITH_WITNESS(block);

    TxVerbosity tx_verbosity;
    if (verbosity == 1) {
        tx_verbosity = TxVerbosity::SHOW_TXID;
    } else if (verbosity == 2) {
        tx_verbosity = TxVerbosity::SHOW_DETAILS;
    } else {
        tx_verbosity = TxVerbosity::SHOW_DETAILS_AND_PREVOUT;
    }

    return blockToJSON(chainman.m_blockman, block, *tip, *pblockindex, tx_verbosity, chainman.GetConsensus().powLimit);
},
    };
}

//! Return height of highest block that has been pruned, or std::nullopt if no blocks have been pruned
std::optional<int> GetPruneHeight(const BlockManager& blockman, const CChain& chain) {
    AssertLockHeld(::cs_main);

    // Search for the last block missing block data or undo data. Don't let the
    // search consider the genesis block, because the genesis block does not
    // have undo data, but should not be considered pruned.
    const CBlockIndex* first_block{chain[1]};

Review comment (bug):
nit: a bunch more of these can be inlined, avoiding the variables named "stream" etc:

<details>
<summary>git diff on fae650c295</summary>

```diff
diff --git a/src/bench/readwriteblock.cpp b/src/bench/readwriteblock.cpp
index 690818f659..b8e226c6eb 100644
--- a/src/bench/readwriteblock.cpp
+++ b/src/bench/readwriteblock.cpp
@@ -21,9 +21,8 @@
 
 static CBlock CreateTestBlock()
 {
-    SpanReader stream{benchmark::data::block413567};
     CBlock block;
-    stream >> TX_WITH_WITNESS(block);
+    SpanReader{benchmark::data::block413567} >> TX_WITH_WITNESS(block);
     return block;
 }
 
diff --git a/src/core_io.cpp b/src/core_io.cpp
index 094f1ec8cc..ec446debee 100644
--- a/src/core_io.cpp
+++ b/src/core_io.cpp
@@ -239,9 +239,8 @@ bool DecodeHexBlockHeader(CBlockHeader& header, const std::string& hex_header)
     if (!IsHex(hex_header)) return false;
 
     const std::vector<unsigned char> header_data{ParseHex(hex_header)};
-    SpanReader ser_header{header_data};
     try {
-        ser_header >> header;
+        SpanReader{header_data} >> header;
     } catch (const std::exception&) {
         return false;
     }
@@ -254,9 +253,8 @@ bool DecodeHexBlk(CBlock& block, const std::string& strHexBlk)
         return false;
 
     std::vector<unsigned char> blockData(ParseHex(strHexBlk));
-    SpanReader ssBlock{blockData};
     try {
-        ssBlock >> TX_WITH_WITNESS(block);
+        SpanReader{blockData} >> TX_WITH_WITNESS(block);
     }
     catch (const std::exception&) {
         return false;
diff --git a/src/rest.cpp b/src/rest.cpp
index 4ecd0f451e..9d73c1e604 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -451,8 +451,7 @@ static bool rest_block(const std::any& context,
     case RESTResponseFormat::JSON: {
         if (tx_verbosity) {
             CBlock block{};
-            SpanReader block_stream{*block_data};
-            block_stream >> TX_WITH_WITNESS(block);
+            SpanReader{*block_data} >> TX_WITH_WITNESS(block);
             UniValue objBlock = blockToJSON(chainman.m_blockman, block, *tip, *pblockindex, *tx_verbosity, chainman.GetConsensus().powLimit);
             std::string strJSON = objBlock.write() + "\n";
             req->WriteHeader("Content-Type", "application/json");
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index 6d4ced7364..d5c9987697 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -832,9 +832,8 @@ static RPCHelpMan getblock()
         return HexStr(block_data);
     }
 
-    SpanReader block_stream{block_data};
     CBlock block{};
-    block_stream >> TX_WITH_WITNESS(block);
+    SpanReader{block_data} >> TX_WITH_WITNESS(block);
 
     TxVerbosity tx_verbosity;
     if (verbosity == 1) {
diff --git a/src/test/fuzz/block.cpp b/src/test/fuzz/block.cpp
index 6e45cc251f..7b87442985 100644
--- a/src/test/fuzz/block.cpp
+++ b/src/test/fuzz/block.cpp
@@ -24,10 +24,9 @@ void initialize_block()
 
 FUZZ_TARGET(block, .init = initialize_block)
 {
-    SpanReader ds{buffer};
     CBlock block;
     try {
-        ds >> TX_WITH_WITNESS(block);
+        SpanReader{buffer} >> TX_WITH_WITNESS(block);
     } catch (const std::ios_base::failure&) {
         return;
     }
diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp
index 820538a54b..70cad07d69 100644
--- a/src/test/fuzz/deserialize.cpp
+++ b/src/test/fuzz/deserialize.cpp
@@ -81,9 +81,8 @@ T Deserialize(DataStream&& ds, const P& params)
 template <typename T, typename P>
 void DeserializeFromFuzzingInput(FuzzBufferType buffer, T&& obj, const P& params)
 {
-    SpanReader ds{buffer};
     try {
-        ds >> params(obj);
+        SpanReader{buffer} >> params(obj);
     } catch (const std::ios_base::failure&) {
         throw invalid_fuzzing_input_exception();
     }
@@ -109,9 +108,8 @@ T Deserialize(DataStream ds)
 template <typename T>
 void DeserializeFromFuzzingInput(FuzzBufferType buffer, T&& obj)
 {
-    SpanReader ds{buffer};
     try {
-        ds >> obj;
+        SpanReader{buffer} >> obj;
     } catch (const std::ios_base::failure&) {
         throw invalid_fuzzing_input_exception();
     }
diff --git a/src/test/fuzz/transaction.cpp b/src/test/fuzz/transaction.cpp
index 224cd9d9b7..8f9c942666 100644
--- a/src/test/fuzz/transaction.cpp
+++ b/src/test/fuzz/transaction.cpp
@@ -41,10 +41,9 @@ FUZZ_TARGET(transaction, .init = initialize_transaction)
         }
     }();
     bool valid_mutable_tx = true;
-    SpanReader ds_mtx{buffer};
     CMutableTransaction mutable_tx;
     try {
-        ds_mtx >> TX_WITH_WITNESS(mutable_tx);
+        SpanReader{buffer} >> TX_WITH_WITNESS(mutable_tx);
     } catch (const std::ios_base::failure&) {
         valid_mutable_tx = false;
     }
diff --git a/src/test/fuzz/tx_in.cpp b/src/test/fuzz/tx_in.cpp
index 4146d96162..10618d60e0 100644
--- a/src/test/fuzz/tx_in.cpp
+++ b/src/test/fuzz/tx_in.cpp
@@ -13,10 +13,9 @@
 
 FUZZ_TARGET(tx_in)
 {
-    SpanReader ds{buffer};
     CTxIn tx_in;
     try {
-        ds >> tx_in;
+        SpanReader{buffer} >> tx_in;
     } catch (const std::ios_base::failure&) {
         return;
     }
diff --git a/src/test/fuzz/tx_out.cpp b/src/test/fuzz/tx_out.cpp
index 1c1016eb92..ce39d14f1a 100644
--- a/src/test/fuzz/tx_out.cpp
+++ b/src/test/fuzz/tx_out.cpp
@@ -12,10 +12,9 @@
 
 FUZZ_TARGET(tx_out)
 {
-    SpanReader ds{buffer};
     CTxOut tx_out;
     try {
-        ds >> tx_out;
+        SpanReader{buffer} >> tx_out;
     } catch (const std::ios_base::failure&) {
         return;
     }
diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp
index e55e1e6f03..136728a043 100644
--- a/src/test/net_tests.cpp
+++ b/src/test/net_tests.cpp
@@ -872,10 +872,9 @@ BOOST_AUTO_TEST_CASE(initial_advertise_from_version_message)
                                         std::span<const unsigned char> data,
                                         bool is_incoming) -> void {
         if (!is_incoming && msg_type == "addr") {
-            SpanReader s{data};
             std::vector<CAddress> addresses;
 
-            s >> CAddress::V1_NETWORK(addresses);
+            SpanReader{data} >> CAddress::V1_NETWORK(addresses);
 
             for (const auto& addr : addresses) {
                 if (addr == expected) {

```
</details>


Code after:
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
    uint256 hash(ParseHashV(request.params[0], "blockhash"));

    int verbosity{ParseVerbosity(request.params[1], /*default_verbosity=*/1, /*allow_bool=*/true)};

    const CBlockIndex* pblockindex;
    const CBlockIndex* tip;
    ChainstateManager& chainman = EnsureAnyChainman(request.context);
    {
        LOCK(cs_main);
        pblockindex = chainman.m_blockman.LookupBlockIndex(hash);
        tip = chainman.ActiveChain().Tip();

        if (!pblockindex) {
            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
        }
    }

    const std::vector<std::byte> block_data{GetRawBlockChecked(chainman.m_blockman, *pblockindex)};

    if (verbosity <= 0) {
        return HexStr(block_data);
    }

    CBlock block{};
    SpanReader{block_data} >> TX_WITH_WITNESS(block);

    TxVerbosity tx_verbosity;
    if (verbosity == 1) {
        tx_verbosity = TxVerbosity::SHOW_TXID;
    } else if (verbosity == 2) {
        tx_verbosity = TxVerbosity::SHOW_DETAILS;
    } else {
        tx_verbosity = TxVerbosity::SHOW_DETAILS_AND_PREVOUT;
    }

    return blockToJSON(chainman.m_blockman, block, *tip, *pblockindex, tx_verbosity, chainman.GetConsensus().powLimit);
},
    };
}

//! Return height of highest block that has been pruned, or std::nullopt if no blocks have been pruned
std::optional<int> GetPruneHeight(const BlockManager& blockman, const CChain& chain) {
    AssertLockHeld(::cs_main);

    // Search for the last block missing block data or undo data. Don't let the
    // search consider the genesis block, because the genesis block does not
    // have undo data, but should not be considered pruned.
    const CBlockIndex* first_block{chain[1]};
    const CBlockIndex* chain_tip{chain.Tip()};